#include <stdio.h>
#include <unistd.h>
#include <pthread.h>
#include <modbus.h>
#include <modbus-tcp.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/shm.h>

#include <errno.h>

enum DEVICE
{
    LED,
    BEEP
};
struct msg
{
    int pos1;
    int pos2;
    int cmd1;
    int cmd2;
};

void *fun(void *arg)
{
    key_t key;
    /*不同进程可以用相同的key值,来访问同一块共享内存 */

    // 创建key值 ftok
    // 第一个参数:以存在的路径名
    key = ftok("/home/carl/demo/httpd/1in_out.c", 'b');
    if (key < 0)
    {
        perror("ftokf err");
        return -1;
    }
    int shmid = shmget(key, 128, IPC_CREAT | IPC_EXCL | 0666);
    if (shmid < 0)
    {
        if (errno == EEXIST)
            shmid = shmget(key, 128, 0666);
        else
        {
            perror("shmget err");
            return -1;
        }
    }
    unsigned short *p = (char *)shmat(shmid, NULL, 0);
    if (p == (char *)-1)
    {
        perror("shmat err");
        return -1;
    }

    modbus_t *ctx = modbus_new_tcp("192.168.0.106", 503);
    if(ctx == NULL)
    {
        perror("failed");
    }
    modbus_set_slave(ctx, 0x1);
    int ff = modbus_connect(ctx);
    if(ff < 0)
    {
        perror("fff");
    }
    unsigned short buf[16] = {0};
    while (1)
    {
        modbus_read_input_registers(ctx, 0x0000, 4, buf);
        for (int i = 0; i < 4; i++)
        {

            p[i] = buf[i];
            printf("0x%.2x ", buf[i]);
        }

        putchar('\n');
        sleep(1);
    }
    modbus_close(ctx);
    modbus_free(ctx);
}
int main(int argc, char const *argv[])
{
    pthread_t thread1;
    pthread_create(&thread1, 0, fun, NULL);
    // modbus_read_input_registers(ctx,0x0000,3, buf);
    modbus_t *ctx = modbus_new_tcp("192.168.0.106", 503);
    modbus_set_slave(ctx, 0x1);
    modbus_connect(ctx);
    unsigned int tmp = 0;
    unsigned int addr = 0;
    unsigned short value = 0;
    key_t key = ftok(".", 'a');
    if (key < 0)
    {
        perror("ftok err");
        return -1;
    }
    // 2.创建或打开消息队列
    int msgid = msgget(key, IPC_CREAT | IPC_EXCL | 0666);
    if (msgid <= 0)
    {
        if (errno == EEXIST)
            msgid = msgget(key, 0666);
        else
        {
            perror("msgget err");
            return -1;
        }
    }
    struct msg msg_r;
    // 0可以匹配任意类型的消息,读的是最前面的消息
    // IPC_NOWAIT:不阻塞,读不到消息函数立即返回

    while (1)
    {
        // puts("请输入:");
        msgrcv(msgid, &msg_r,
               sizeof(msg_r), 0, 0);
        printf("key:%d %d\n", msg_r.cmd1, msg_r.cmd2);
        modbus_write_register(ctx, LED, msg_r.cmd1);
        modbus_write_register(ctx, BEEP, msg_r.cmd2);
    }
    pthread_join(thread1, NULL);
    modbus_close(ctx);
    modbus_free(ctx);
    return 0;
}
